// IOCPModelDemo.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include "CIOCPServerModel.h"

#include "memleak/MemLeak.h"
#include "DumpReport.h"

#include "IOCPAppImpl.h"

#include <string>
#include <Windows.h>
#include <wtsapi32.h>
#pragma comment(lib, "wtsapi32.lib")



int memleakTest();

int createfilemap()
{
    HANDLE hFile = CreateFile(L"D:\\mapfile",
        GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_READ,
        NULL,
        CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL,
        NULL);
    if (hFile == INVALID_HANDLE_VALUE)
    {
        //cout << " CreateFile fail" << endl;
        return -1;
    }

    //创建一个文件映射内核对象
    HANDLE hFileMap = CreateFileMappingW(hFile, NULL, PAGE_READWRITE,
        0, 40 * 1024 * 1024, NULL);
    if (hFileMap == NULL)
    {
        //cout << "CreateFileMapping fail" << endl;
        return -1;
    }

    //将文件数据映射到进程的地址空间
    char* pMapData = (char*)MapViewOfFile(hFileMap,
        FILE_MAP_ALL_ACCESS,
        NULL,
        NULL,
        NULL);
    if (pMapData == NULL)
    {
        //cout << " MapViewOfFile fail" << endl;
        return -1;
    }

    return 0;
}

static DWORD WINAPI SendThreadTest(LPVOID param)
{
    int id = 0;
    char szBuf[25] = { 0 };
    while (1)
    {
        sprintf_s(szBuf, "lzlong send data %d", id++);
        //pIOCPModel->SendDataByConnectID(0, szBuf, (ULONG)(strlen(szBuf) + 1));
        CIOCPAppSrvBase::SendDataByConnectID(1, szBuf, (ULONG)(strlen(szBuf) + 1));
        Sleep(500);
    }
    return 0;
}

std::string get_disk_smart_serials(int index)
{
    std::string ret;

    char physical[256]{ 0 };
    sprintf_s(physical, 256, "\\\\.\\PhysicalDrive%d", index);

    HANDLE disk = CreateFileA(physical, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
    if (disk != INVALID_HANDLE_VALUE)
    {
        STORAGE_PROPERTY_QUERY query{ };
        query.PropertyId = StorageDeviceProperty;
        query.QueryType = PropertyStandardQuery;

        const int b_size = 1024 * 10;
        char* buf = new char[b_size];
        if (buf)
        {
            memset(buf, 0, b_size);
            DWORD r = 0;
            BOOL status = DeviceIoControl(disk, IOCTL_STORAGE_QUERY_PROPERTY, &query, sizeof(query), buf, b_size, &r, NULL);
            if (status)
            {
                STORAGE_DEVICE_DESCRIPTOR* descrip = (STORAGE_DEVICE_DESCRIPTOR*)buf;
                if (descrip->SerialNumberOffset > 0)
                {
                    std::string serial = buf + descrip->SerialNumberOffset;
                    serial.erase(std::remove_if(serial.begin(), serial.end(), [](unsigned char x) {return std::isspace(x); }), serial.end());
                    ret = serial;
                }
            }

            delete[] buf;
        }

        CloseHandle(disk);
    }

    return ret;
}

std::string getUserName(int sessionId) {
    std::string userName;
    // WTSQuerySessionInformation
    LPSTR pBuffer = NULL;
    DWORD bytesReturned = 0;
    if (WTSQuerySessionInformationA(WTS_CURRENT_SERVER_HANDLE, sessionId, WTS_INFO_CLASS::WTSUserName, &pBuffer, &bytesReturned))
    {
        userName.assign(pBuffer);
    }
    if (pBuffer)
    {
        WTSFreeMemory(pBuffer);
    }
    return userName;
}

int main()
{

    DumpReport dmpreport;
    dmpreport.InitDumpReport(L"3.4.56.7", FALSE);

    //HANDLE h3 = OpenEvent(EVENT_MODIFY_STATE, FALSE, L"Event3");
    //SetEvent(h3);

    //HANDLE h1 = OpenEvent(EVENT_MODIFY_STATE, FALSE, L"Event1");
    //SetEvent(h1);

    //createfilemap();

#if 0
    char* p11 = NULL;
    //*p11 = 'd';
    memleakTest();
    HANDLE _crtheap = HeapCreate(0, 4096, 0);
    //LPVOID p0 = HeapAlloc(_crtheap, 0, 30*1024*1024);
 //   new char[30 * 1024 * 1024];
    char* p = (char*)::HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 40 * 1024 * 1024);
    LPVOID p2 = VirtualAlloc(NULL, 40 * 1024 * 1024, MEM_COMMIT, PAGE_READWRITE);

    //VirtualFree(p2, 0, MEM_RELEASE);

    //::HeapFree(GetProcessHeap(), 0, p);
    //MessageBox(NULL, L"sdf", L"sdfa", NULL);
    new char[52];
#endif

    malloc(34);
/*    CIOCPServerModel IOCPModel;
    IOCPModel.Start();
    getchar();
    IOCPModel.Stop();  */

    CSambaIOCPSrvImpl* pSamba1 = new CSambaIOCPSrvImpl("127.0.0.1", 12345);
    pSamba1->StartServer();
    CSambaIOCPSrvImpl* pSamba2 = new CSambaIOCPSrvImpl("127.0.0.1", 2345);
    pSamba2->StartServer();

    auto hThread = CreateThread(NULL, 0, SendThreadTest, 0, 0, NULL);
   
    getchar();
    if (hThread)
    {
        TerminateThread(hThread, 0);
        ::CloseHandle(hThread);
        hThread = INVALID_HANDLE_VALUE;
    }

    CIOCPAppSrvBase::DisconnectByIOCPAppType(APP_SAMB_PROXY);

    std::string username = getUserName(1);
    //const char* p = "sdfasdfa";
    //delete p;

    pSamba1->StopServer();
    pSamba2->StopServer();
    delete pSamba1;
    delete pSamba2;
    std::cout << "Hello World!\n";
}

int memleakTest()
{
    _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG);
    std::cout << "Hello World!\n";
    int* x = (int*)malloc(sizeof(int));
    *x = 7;
    printf("%d\n", *x);
    x = (int*)calloc(3, sizeof(int));
    x[0] = 7;
    x[1] = 77;
    x[2] = 777;

    printf("%d %d %d\n", x[0], x[1], x[2]);
    
    _CrtDumpMemoryLeaks();
    return 0;
}